#include "Vector2d.h"
#include <stdlib.h>
#include <math.h>
#include <assert.h>

static const int VSIZE = 2;
static inline ValueType vector2d_dot_impl(Vector2d* a, Vector2d* b);

static inline ValueType vector2d_dot_impl(Vector2d* a, Vector2d* b)
{
	ValueType dot = 0;
	for (int i = 0; i < a->size; ++i)
		dot += a->data[i] * b->data[i];
	return dot;
}


Vector2d* vector2d_create(ValueType d[])
{
	Vector2d* v = (Vector2d*)malloc(sizeof(Vector2d));
	assert(v);
	v->size = VSIZE;
	for (int i = 0; i < VSIZE; ++i)
		v->data[i] = d[i];
	return v;
}

Vector2d* vector2d_free(Vector2d* vector)
{
	if (vector)
		free(vector);
	return NULL;
}

Vector2d* vector2d_add(Vector2d* a, Vector2d* b, Vector2d* c)
{
	assert(a && b && c);
	assert(a->size == VSIZE);
	assert(b->size == VSIZE);
	*c = *a;
	for (int i = 0; i < c->size; ++i)
		c->data[i] += b->data[i];
	return c;
}

Vector2d* vector2d_sub(Vector2d* a, Vector2d* b, Vector2d* c)
{
	assert(a && b && c);
	assert(a->size == VSIZE);
	assert(b->size == VSIZE);
	if (c != a)
		*c = *a;
	for (int i = 0; i < c->size; ++i)
		c->data[i] -= b->data[i];
	return c;
}

Vector2d* vector2d_mul_scalar(Vector2d* a, ValueType k, Vector2d* b)
{
	assert(a && b);
	assert(a->size == VSIZE);
	if (a != b)
		* b = *a;
	for (int i = 0; i < b->size; ++i)
		b->data[i] *= k;
	return b;
}

ValueType vector2d_dot(Vector2d* a, Vector2d* b)
{
	assert(a && b);
	assert(a->size == VSIZE);
	assert(b->size == VSIZE);
	return vector2d_dot_impl(a, b);
}

ValueType vector2d_cross(Vector2d* a, Vector2d* b)
{
	assert(a && b);
	assert(a->size == VSIZE);
	assert(b->size == VSIZE);
	return a->data[0] * b->data[1] - a->data[1] * b->data[0];
}

ValueType vector2d_norm(Vector2d* a)
{
	assert(a);
	assert(a->size == VSIZE);
	ValueType norm = vector2d_dot_impl(a, a);
	return sqrt(norm);
}

Vector2d* vector2d_normalize(Vector2d* a)
{
	assert(a);
	assert(a->size == VSIZE);
	ValueType norm = vector2d_norm(a);
	if (norm>0)
		for (int i = 0; i < a->size; ++i)
			a->data[i] /= norm;
	return a;
}

/*

*/